import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;

/**
 * 酒店房间预定管理系统主程序类
 * 
 * 这是整个酒店管理系统的入口类和主控制器
 * 负责系统的初始化、界面管理和全局配置
 * 
 * 主要职责：
 * 1. 系统启动和初始化
 * 2. 管理主窗口和界面切换
 * 3. 定义全局的UI主题（颜色、字体等）
 * 4. 协调各个功能模块
 * 
 * 设计模式：
 * - 单例模式：整个系统只有一个主窗口
 * - MVC模式：这个类是Controller，负责控制界面切换
 * - 观察者模式：监听用户操作，响应界面切换请求
 * 
 * 技术特点：
 * - 使用Java Swing构建桌面应用程序
 * - 采用CardLayout实现多界面切换
 * - 统一的UI主题设计
 * - 响应式界面布局
 * 
 * @author Hotel Management System
 * @version 1.0
 * @since 2025-01-01
 */
public class HotelManagementSystem extends JFrame {

    // ==================== 全局UI主题配置 ====================
    // 这些静态常量定义了整个系统的视觉风格
    // 使用静态常量的好处：
    // 1. 全局统一：所有界面使用相同的颜色和字体
    // 2. 易于维护：修改一处，全系统生效
    // 3. 性能优化：避免重复创建相同的对象

    /**
     * 主色调 - 深蓝色
     * 用于：标题、主要按钮、重要文字
     * RGB值：(41, 128, 185) - 专业、稳重的蓝色
     */
    private static final Color PRIMARY_COLOR = new Color(41, 128, 185);

    /**
     * 次要色调 - 亮蓝色
     * 用于：次要按钮、悬停效果、装饰元素
     * RGB值：(52, 152, 219) - 比主色调更亮的蓝色
     */
    private static final Color SECONDARY_COLOR = new Color(52, 152, 219);

    /**
     * 强调色 - 红色
     * 用于：警告、删除、取消等操作
     * RGB值：(231, 76, 60) - 醒目的红色
     */
    private static final Color ACCENT_COLOR = new Color(231, 76, 60);

    /**
     * 成功色 - 绿色
     * 用于：确认、保存、成功等操作
     * RGB值：(39, 174, 96) - 清新的绿色
     */
    private static final Color SUCCESS_COLOR = new Color(39, 174, 96);

    /**
     * 背景色 - 浅灰色
     * 用于：面板背景、表格头部等
     * RGB值：(236, 240, 241) - 柔和的浅灰色
     */
    private static final Color BACKGROUND_COLOR = new Color(236, 240, 241);

    /**
     * 标题字体
     * 微软雅黑，粗体，24号字
     * 用于：主标题、重要标题
     */
    private static final Font TITLE_FONT = new Font("微软雅黑", Font.BOLD, 24);

    /**
     * 按钮字体
     * 微软雅黑，普通，14号字
     * 用于：按钮、标签、普通文字
     */
    private static final Font BUTTON_FONT = new Font("微软雅黑", Font.PLAIN, 14);

    // ==================== 界面组件 ====================
    // 这些成员变量管理主窗口的各个界面组件

    /**
     * 主面板 - 容纳所有界面的容器
     * 使用CardLayout布局，可以在多个界面之间切换
     */
    private JPanel mainPanel;

    /**
     * 卡片布局管理器
     * 用于管理多个界面的显示和切换
     * 每个界面都是一张"卡片"，同时只显示一张
     */
    private CardLayout cardLayout;

    /**
     * 登录面板
     * 系统启动时首先显示的界面
     * 用户需要输入用户名和密码才能进入系统
     */
    private LoginPanel loginPanel;

    /**
     * 主菜单面板
     * 登录成功后显示的主界面
     * 包含所有功能模块的入口
     */
    private MainMenuPanel mainMenuPanel;

    /**
     * 构造方法 - 创建并初始化酒店管理系统
     * 
     * 这是系统的入口点，负责：
     * 1. 初始化数据文件
     * 2. 设置用户界面
     * 3. 显示主窗口
     * 
     * 调用顺序很重要：
     * 1. 先初始化系统（数据文件等）
     * 2. 再设置界面
     * 3. 最后显示窗口
     */
    public HotelManagementSystem() {
        // 第一步：初始化系统数据
        initializeSystem();

        // 第二步：设置用户界面
        setupUI();

        // 第三步：显示主窗口
        setVisible(true);
    }

    /**
     * 初始化系统数据
     * 
     * 这个方法在界面创建之前调用，负责：
     * 1. 创建必要的数据文件夹
     * 2. 初始化数据文件（如果不存在）
     * 3. 设置默认数据
     * 
     * 为什么要先初始化数据？
     * - 界面显示需要读取数据
     * - 确保系统有基本的运行环境
     * - 避免运行时出现文件不存在的错误
     */
    private void initializeSystem() {
        // 调用DataManager的单例方法初始化数据文件
        // DataManager负责所有的文件操作
        DataManager.getInstance().initializeDataFiles();
    }

    /**
     * 设置用户界面
     * 
     * 这个方法负责创建和配置主窗口的所有组件
     * 包括：
     * 1. 窗口基本属性（标题、大小、位置等）
     * 2. 创建主面板和布局管理器
     * 3. 创建各个功能面板
     * 4. 设置默认显示的界面
     */
    private void setupUI() {
        // ==================== 窗口基本设置 ====================

        // 设置窗口标题，显示在标题栏上
        setTitle("酒店房间预定管理系统");

        // 设置窗口关闭操作
        // EXIT_ON_CLOSE：点击关闭按钮时退出整个程序
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 设置窗口大小：宽1200像素，高800像素
        // 这个大小适合大多数现代显示器
        setSize(1200, 800);

        // 设置窗口居中显示
        // null参数表示相对于屏幕居中
        setLocationRelativeTo(null);

        // 设置窗口可以调整大小
        // true：用户可以拖拽窗口边缘改变大小
        setResizable(true);

        // ==================== 创建主面板和布局 ====================

        // 创建CardLayout布局管理器
        // CardLayout像一叠卡片，同时只显示最上面的一张
        cardLayout = new CardLayout();

        // 创建主面板，使用CardLayout布局
        mainPanel = new JPanel(cardLayout);

        // ==================== 创建各个功能面板 ====================

        // 创建登录面板，传入this引用，让登录面板可以控制主窗口
        loginPanel = new LoginPanel(this);
        // 将登录面板添加到主面板，标识名为"LOGIN"
        mainPanel.add(loginPanel, "LOGIN");

        // 创建主菜单面板，传入this引用
        mainMenuPanel = new MainMenuPanel(this);
        // 将主菜单面板添加到主面板，标识名为"MAIN_MENU"
        mainPanel.add(mainMenuPanel, "MAIN_MENU");

        // ==================== 设置主面板 ====================

        // 将主面板添加到窗口中
        // BorderLayout.CENTER表示占据窗口的中央区域
        add(mainPanel);

        // ==================== 设置默认显示界面 ====================

        // 系统启动时显示登录界面
        showLoginPanel();
    }

    /**
     * 显示登录面板
     * 
     * 这个方法用于切换到登录界面
     * 通常在以下情况调用：
     * 1. 系统启动时
     * 2. 用户退出登录时
     * 3. 会话超时时
     */
    public void showLoginPanel() {
        // 使用CardLayout的show方法切换界面
        // 第一个参数是容器（mainPanel）
        // 第二个参数是要显示的卡片标识（"LOGIN"）
        cardLayout.show(mainPanel, "LOGIN");
    }

    /**
     * 显示主菜单
     * 
     * 这个方法用于切换到主菜单界面
     * 通常在用户登录成功后调用
     * 
     * 除了切换界面，还会刷新数据，确保显示最新信息
     */
    public void showMainMenu() {
        // 切换到主菜单界面
        cardLayout.show(mainPanel, "MAIN_MENU");

        // 刷新主菜单的数据
        // 这确保用户看到的是最新的房间状态、入住信息等
        mainMenuPanel.refreshData();
    }

    /**
     * 程序入口点 - main方法
     * 
     * 这是Java程序的标准入口点
     * JVM（Java虚拟机）启动程序时会首先调用这个方法
     * 
     * 方法签名说明：
     * - public：公共方法，可以被外部调用
     * - static：静态方法，不需要创建对象就能调用
     * - void：无返回值
     * - String[] args：命令行参数数组
     * 
     * @param args 命令行参数（本程序中未使用）
     */
    public static void main(String[] args) {
        // 使用SwingUtilities.invokeLater确保界面在事件分发线程中创建
        // 这是Swing编程的最佳实践，避免线程安全问题
        //
        // 为什么要这样做？
        // 1. Swing不是线程安全的
        // 2. 所有UI操作都应该在事件分发线程（EDT）中进行
        // 3. invokeLater将任务放入EDT的事件队列中执行
        SwingUtilities.invokeLater(() -> {
            // 使用Lambda表达式创建HotelManagementSystem对象
            // 这等价于：SwingUtilities.invokeLater(new Runnable() {
            // public void run() {
            // new HotelManagementSystem();
            // }
            // });
            new HotelManagementSystem();
        });
    }

    // ==================== 静态方法 - 全局主题访问器 ====================
    // 这些静态方法提供对全局主题配置的访问
    // 其他类可以通过这些方法获取统一的颜色和字体
    //
    // 为什么使用静态方法？
    // 1. 不需要创建对象就能访问
    // 2. 全局唯一，确保主题一致性
    // 3. 便于其他类使用

    /**
     * 获取主色调
     * 
     * 其他类可以调用这个方法获取系统的主色调
     * 例如：Color primaryColor = HotelManagementSystem.getPrimaryColor();
     * 
     * @return 主色调颜色对象
     */
    public static Color getPrimaryColor() {
        return PRIMARY_COLOR;
    }

    /**
     * 获取次要色调
     * 
     * @return 次要色调颜色对象
     */
    public static Color getSecondaryColor() {
        return SECONDARY_COLOR;
    }

    /**
     * 获取强调色
     * 
     * @return 强调色颜色对象
     */
    public static Color getAccentColor() {
        return ACCENT_COLOR;
    }

    /**
     * 获取成功色
     * 
     * @return 成功色颜色对象
     */
    public static Color getSuccessColor() {
        return SUCCESS_COLOR;
    }

    /**
     * 获取背景色
     * 
     * @return 背景色颜色对象
     */
    public static Color getBackgroundColor() {
        return BACKGROUND_COLOR;
    }

    /**
     * 获取标题字体
     * 
     * @return 标题字体对象
     */
    public static Font getTitleFont() {
        return TITLE_FONT;
    }

    /**
     * 获取按钮字体
     * 
     * @return 按钮字体对象
     */
    public static Font getButtonFont() {
        return BUTTON_FONT;
    }
}